package week7.hotel;

import java.io.PrintStream;
import java.util.ArrayList;
import java.util.List;

import week7.intlist.IntegerList;
import week7.ww.Wachtwoord;

/**
 * Hotel klasse, gemaakt voor Programmeren I
 * Practicumopgave Programmeren I
  * @author W.Looge & R. Oost
  * @version 1.0
  */
public class Hotel {

	/**
	 * String waarin de naam van het hotel wordt opgeslagen
	 */
    private String naam;
    /**
     * Wachtwoord-object dat wordt gebruikt om het wachtwoord bij te houden
     */
    private Wachtwoord pass = new Wachtwoord();
    
    /**
     * Lijst van alle kamers.
     */
    public List<Kamer> kamers;
    
    /**
     * Constructor, maakt een nieuw hotel met de opgegeven naam
     * @param hotelnaam Naam voor het hotel
     */
    public Hotel(String hotelnaam, IntegerList kamernummers) {
        this.naam = hotelnaam;
        this.kamers = new ArrayList<Kamer>();
        
        for(int x = 0; x < kamernummers.size(); x++) {
        	if(kamernummers.get(x) > 0 && kamernummers.indexOf(kamernummers.get(x)) == x) {
        		kamers.add(new PrijzigeKamer(kamernummers.get(x), 50, 5));
        	}
        }
    }
    
    /**
     * Checkt de gast met naam <code>gastnaam</code> in, in een vrije kamer.
     * @param wachtwoord String met het benodigde wachtwoord om een gast in te checken.
     * @param gastnaam String met de naam van de in te checken gast.
     * @return Kamer De kamer waarin de gast is ingecheckt.
     * @ensure if(pass.testWoord(wachtwoord) && old.getKamer(gastnaam) == null -Dan- Gast is ingecheckt in een kamer.
     */
    public Kamer checkin(String wachtwoord, String gastnaam) {
        if (pass.testWoord(wachtwoord) && getKamer(gastnaam) == null && !gastnaam.equals("")) {
            Gast g = new Gast(gastnaam);
            Kamer k = this.getVrijeKamer();
            if (k==null) return null; //Als er geen lege kamers meer zijn, return dan null
            g.checkin(k);
            return k;
        }
        return null;
    }
    
    /**
     * Check de gast met naam <code>gastnaam</code> uit.
     * @param gastnaam String met de naam van de uit te checken gast.
     * @ensure Gast is uitgecheckt en de kamer is leeg.
     */
    public void checkuit(String gastnaam) {
        Kamer k = this.getKamer(gastnaam);
        if (k != null) {
            k.getGast().checkuit();
        }
    }
    
    //-----------------------Queries----------------------
    
    /**
    * Vindt een vrije kamer.
    * @ensure De teruggegeven kamer is niet bezet
    * @return Kamer Een vrije kamer.
    *         null als er geen vrije kamer is gevonden
    */
    public Kamer getVrijeKamer() {
    	List<Kamer> vrijekamers = getVrijeKamers();
    	if (vrijekamers.size() != 0) {
    		return vrijekamers.get(0);
    	} else {
    		return null;
    	}
    }
    
    /**
     * Geeft de lijst met alle vrije kamers.
     * @ensure Alle kamers in de lijst zijn niet bezet.
     * @return List<Kamer> Lijst van alle vrije kamers.
     */
    public List<Kamer> getVrijeKamers() {
    	List<Kamer> result = new ArrayList<Kamer>();
    	for (int x = 0; x < this.kamers.size(); x++) {
    		if (this.kamers.get(x).getGast() == null) {
    			result.add(this.kamers.get(x));
    		}
    	}
    	return result;
    }
    
    /**
    * Vindt de kamer waarin de Gast met de opgegeven <code>gastnaam</code> is ingecheckt.
    * @return Kamer De kamer waar deze gast is ingecheckt
    * @return null Deze gast is niet bekend
    */
    public Kamer getKamer(String gastnaam) {
    	for(int x = 0; x < this.kamers.size(); x++) {
    		if(this.kamers.get(x).getGast() != null) {
    			if (this.kamers.get(x).getGast().getNaam().equals(gastnaam)) return this.kamers.get(x);
    		}
    	}
    	return null;
    }
    
    /**
     * Levert het wachtwoord object op dat dit hotel gebruikt voor het hoofd-wachtwoord
     * @return Wachtwoord Het wachtwoord object
     */
    public Wachtwoord getWachtwoord() {
        return pass;
    }
    /**
     * Levert de naam van dit hotel op
     * @return String Naam van dit hotel
     */
    public String getNaam() {
        return this.naam;
    }
    
    /**
     * Print de rekening van de opgegeven gast voor het opgegeven aantal nachten op de opgegeven PrintStream
     * @param gastnaam De naam van de gast.
     * @param overnachtingen Het aantal overnachtingen voor deze gast.
     * @param out De PrintStream waar de rekening op moet worden geprint.
     * @return null als deze gast niets hoeft te betalen
     */
    public Rekening getRekening(String gastnaam, int overnachtingen, PrintStream out) {
    	Rekening rekening = new Rekening(out);
    	Kamer k = this.getKamer(gastnaam);
    	
    	if (k == null) {
    		//Deze gast is onbekend
    		return null;
    	}
    	
    	//Als de kamer geen PrijzigeKamer is dan moet hij null terug geven
    	if (!(k instanceof PrijzigeKamer)) {
    		//Deze gast verblijft in een gratis kamer
    		return null;
    	}
    	
    	//Print de titel van de rekening
    	out.println("\nRekening van " + gastnaam + ":\n");
    	
    	// Zet de overnachtingen op de rekening
    	for(int x=1;x<=overnachtingen;x++) {
    		rekening.nieuwItem((PrijzigeKamer) k);
    	}
    	
    	// Als de kluis een PrijzigeKluis is dan moet dat ook bij de rekening
    	if (k.getKluis().isActief() && k.getKluis() instanceof PrijzigeKluis) {
    		rekening.nieuwItem((PrijzigeKluis) k.getKluis());
    	}
    	
    	// Totaalbedrag
    	rekening.sluitAf();
    	return rekening;
	}
    
    /**
     * Levert een tekstuele representatie van dit hotel op
     * @return String "Hotel " + hotelnaam
     */
    public String toString() {
    	String result = "Hotel " + this.getNaam() + ":";
    	
    	for(int x = 0; x < kamers.size(); x++) {
    		result = result + "\n    " + kamers.get(x) + ":";
    		result = result + "\n        Gehuurd door   : " + kamers.get(x).getGast();
    		result = result + "\n        Kluisje actief : " + kamers.get(x).getKluis().isActief();
    	}
    	
    	return result;
    }
}